const app = getApp()
const tf = require('@tensorflow/tfjs-core')
const posenet = require("@tensorflow-models/posenet")
const regeneratorRuntime = require("regenerator-runtime")

Page({
    data: {
        // pos: {
        //     xScale: 0.8,
        //     yScale: 1.1
        // },
        pos: { //手机用的
            xScale: 1.4,
            yScale: 2.15
        },
    },
    async onReady() {
        const camera = wx.createCameraContext(this)
        this.canvas = wx.createCanvasContext('pose', this);
        this.loadPosenet()
        let count = 0;
        const listener = camera.onCameraFrame((frame) => {
            count++;
            if (count === 1) {
                if (this.net) {
                    this.drawPose(frame)
                }
                count = 0;
            }
        })
        listener.start()
    },
    async drawPose(frame) {
        const pose = await this.detectPose(frame, this.net);
        if (pose == null || this.canvas == null) return
        if (pose.score >= 0.3) {
            for (let i in pose.keypoints) {
                const point = pose.keypoints[i]
                if (point.score >= 0.5) {
                    const { x, y } = point.position;
                    this.drawCircle(this.canvas, x, y)
                }
            }
            const adJacentKayPoints = posenet.getAdjacentKeyPoints(pose.keypoints, 0.5)
            for (let i in adJacentKayPoints) {
                const points = adJacentKayPoints[i]
                this.drawLine(this.canvas, points[0].position, points[1].position)
            }
            this.canvas.draw()
        }

    },
    drawLine(canvas, pos0, pos1) {
        const { pos } = this.data
        canvas.beginPath()
        canvas.moveTo(pos0.x * pos.xScale, pos0.y * pos.yScale)
        canvas.lineTo(pos1.x * pos.xScale, pos1.y * pos.yScale)
        canvas.lineWidth = 2
        canvas.strokeStyle = 'aqua'
        canvas.stroke()
    },
    drawCircle(canvas, x, y) {
        const { pos } = this.data
        canvas.beginPath()
        canvas.arc(
            x * pos.xScale,
            y * pos.yScale,
            3,
            0,
            2 * Math.PI
        )
        canvas.fillStyle = 'aqua'
        canvas.fill()
    },
    async detectPose(frame, net) {
        const imgData = { data: new Uint8Array(frame.data), width: frame.width, height: frame.height }
        const imgSlice = tf.tidy(() => {
            const imgTensor = tf.browser.fromPixels(imgData, 4)
            return tf.slice(imgTensor, [0, 0, 0], [-1, -1, 3])
        })
        const pose = await net.estimateSinglePose(imgSlice, {
            flipHorizontal: false
        });
        tf.dispose(imgSlice)
        return pose
    },
    async loadPosenet() {
        this.net = await posenet.load({
            architecture: 'MobileNetV1',
            outputStride: 16,
            inputResolution: 193,
            multiplier: 0.5,
            modelUrl: "https://www.gstaticcnapps.cn/tfjs-models/savedmodel/posenet/mobilenet/float/050/model-stride16.json"
        })
    },
    error: function(err) {}
})